
PM_FUNC_PUBLIC_ATTRIB CommandPokemod( Int:iPlayer, Int:iCmdLevel, Int:iCommandID )
{
	if ( g_iState == PM_DISABLED )
	{
		console_print( iPlayer, "PokeMod is currently disabled" );
		new Int:iMissingFiles = PokeModMissingFiles();
		if ( iMissingFiles )
		{
			console_print( iPlayer, "PokeMod is missing %d file%c", iMissingFiles, iMissingFiles == 1 ? 's' : EOS );
		}
		return PLUGIN_HANDLED;
	}

	console_print( iPlayer, "[PokeMod Plugin Information" );
	console_print( iPlayer, "[Version : %s", g_szVersion );
	console_print( iPlayer, "[PokeMod Team : Emp`" );

	return PLUGIN_HANDLED;
}

PM_FUNC_PUBLIC_ATTRIB CommandSay( Int:iPlayer )
{
	new String:szSaid[ 192 ], Int:iCommandStart;
	read_args( szSaid, charsmax(szSaid) );
	remove_quotes( szSaid );
	trim( szSaid );

	pokemod_funcstart_debug( "CommandSay '%s'", szSaid );

	//ignore the / if it is there
	if ( szSaid[ 0 ] == '/' )
	{
		iCommandStart = 1;
	}

	if ( ( containi( szSaid[ iCommandStart ], "say" ) != -1 ) || ( containi( szSaid[ iCommandStart ], "type" ) != -1 ) )
	{
		pokemod_funcend_debug( "CommandSay say/type" );
		return PLUGIN_CONTINUE;
	}

	if ( g_iState == PM_DISABLED )
	{
		if ( containi( szSaid[ iCommandStart ], "poke" ) != -1 )
		{
			client_print( 0, print_chat, "[PokeMod] PokeMod is currently disabled." );
		}

		pokemod_funcend_debug( "CommandSay Disabled" );
		return PLUGIN_CONTINUE;
	}

	new PM_MENUS:iMenuType = g_iPlayerMenuType[ iPlayer ];
	switch ( iMenuType )
	{
		case MENU_COMMAND, MENU_ADMINCOMMAND, MENU_USE_ITEM:
		{
			if ( MenuFilter( iPlayer, szSaid[ iCommandStart ], iMenuType ) )
			{
				pokemod_funcend_debug( "CommandSay Menu Filtered" );
				return PLUGIN_HANDLED;
			}
		}
	}

	new String:szCommand[ 64 ], String:szArg1[ 64 ], String:szArg2[ 64 ];
	parse( szSaid[ iCommandStart ], szCommand, charsmax(szCommand), szArg1, charsmax(szArg1), szArg2, charsmax(szArg2) );

	if ( containi( szCommand, "pm" ) != -1 || ( containi( szSaid[ iCommandStart ], "menu" ) != -1 && containi( szSaid[ iCommandStart ], "poke" ) != -1 ) )
	{
		MenuMain( iPlayer, .bForceDisplay = false );

		pokemod_funcend_debug( "CommandSay Main Menu" );
		return PLUGIN_CONTINUE;
	}

	else if ( equali( szCommand, "go" ) )
	{
		if ( szSaid[ iCommandStart + 2 ] == ' ' )
		{
			new Int:iPokeNum = NameToPokeNum( szSaid[ iCommandStart + 3 ], .playerID = iPlayer );
			if ( iPokeNum != -1 )
			{
				PlayerChangePokemon( iPlayer, iPokeNum, .bForced = false );
			}
		}
		else if ( szSaid[ iCommandStart + 2 ] == EOS )
		{
			MenuChangePokemon( iPlayer );
		}

		pokemod_funcend_debug( "CommandSay Go Menu" );
		return PLUGIN_CONTINUE;
	}

	else if ( equali( szCommand, "backpack" ) || equali( szCommand, "bp" ) )
	{
		MenuBackPack( iPlayer );

		pokemod_funcend_debug( "CommandSay BackPack Menu" );
		return PLUGIN_CONTINUE;
	}

	else if ( equali( szCommand, "items" ) || equali( szCommand, "myitem", 6 ) )
	{
		ItemMenu( iPlayer );

		pokemod_funcend_debug( "CommandSay Item Menu" );
		return PLUGIN_CONTINUE;
	}

	else if ( ( equali( szCommand, "pc" ) || equali( szCommand, "send" ) || equali( szCommand, "recieve" ) )
		&& PlayerHasItem( iPlayer, NameToItem( "Pocket PC" ) ) != -1 )
	{
		MenuPC( iPlayer );

		pokemod_funcend_debug( "CommandSay PC Menu" );
		return PLUGIN_CONTINUE;
	}

	else if ( equali( szCommand, "run" ) )
	{
		if ( EncounterRun( iPlayer ) )
		{
			pokemod_funcend_debug( "CommandSay Run" );
			return PLUGIN_CONTINUE;
		}
	}

	else if ( equali( szCommand, "trade" ) )
	{
		new Int:iTradePlayer = NameToPlayer( szArg1 );
		if ( iTradePlayer == iPlayer )
			iTradePlayer = 0;
		TradeClear( iPlayer, iTradePlayer );
		TradeMenu( iPlayer );

		pokemod_funcend_debug( "CommandSay Trade Menu" );
		return PLUGIN_CONTINUE;
	}

	else if ( containi( szCommand, "poke" ) != -1 && ( containi( szCommand, "info" ) != -1 || containi( szCommand, "dex" ) != -1 || equali( szCommand, "pokemon" ) ) )
	{
		new Int:iPoke = str_to_num( szArg1 );
		if ( iPoke <= 0 )
			iPoke = NameToPoke( szArg1, .playerID = iPlayer );

		if ( iPoke <= 0 )
		{
			if ( strlen( szArg1 ) > 0 )
				client_print( iPlayer, print_chat, "[PokeMod] Could not identify '%s' as a valid pokemon.", szArg1 );
			CommandPokeMenu( iPlayer, "say /pokedex", .bOnlyOwned = false );
		}
		else
			PlayerPokedex( iPlayer, iPoke );
	}

	else if ( containi( szCommand, "skill" ) != -1 && ( containi( szCommand, "info" ) != -1 || containi( szCommand, "dex" ) != -1 || containi( szCommand, "help" ) != -1 || containi( szCommand, "poke" ) != -1 ) )
	{
		new POKESKILL:iSkillID = NameToSkill( szArg1, .playerID = iPlayer );
		if ( iSkillID == SKILL_INVALID )
		{
			if ( strlen( szArg1 ) > 0 )
				client_print( iPlayer, print_chat, "[PokeMod] Could not identify '%s' as a valid skill.", szArg1 );
			CommandPokeMenu( iPlayer, "say /skilldex", .bOnlyOwned = false );
		}
		else
			PlayerSkillHelp( iPlayer, iSkillID );
	}

	else if ( ( equali( szCommand, "map" ) && !is_map_valid( szArg1 ) ) || equali( szCommand, "location" ) )
	{
		new Int:iLocation = NameToLocation( szArg1, .playerID = iPlayer );
		if ( iLocation <= -1 )
		{
			if ( strlen( szArg1 ) > 0 )
				client_print( iPlayer, print_chat, "[PokeMod] Could not identify '%s' as a valid location.", szArg1 );
			CommandLocationMenu( iPlayer, "say /location" );
		}
		else
			PlayerViewMap( iPlayer, iLocation );
	}

	else if ( equali( szCommand, "use" ) || ( containi( szCommand, "use" ) != -1 || containi( szCommand, "item" ) != -1 ) )
	{
		new Int:iItemID = NameToItem( szArg1, .playerID = iPlayer );
		if ( iItemID <= -1 )
		{
			if ( strlen( szArg1 ) > 0 )
				client_print( iPlayer, print_chat, "[PokeMod] Could not identify '%s' as a valid item.", szArg1 );
			ItemMenu( iPlayer );
		}
		else
			ItemUse( iPlayer, iItemID );
	}

	else if ( containi( szCommand, "switch" ) != -1 )
	{
		new LIST_TYPES:iList, Int:iNum1 = -1, Int:iNum2 = -1;
		if ( containi( szCommand, "poke" ) != -1 )
		{
			iList = LIST_POKEMON_NICKNAMES;
			iNum1 = NameToPokeNum( szArg1, .playerID = iPlayer );
			iNum2 = NameToPokeNum( szArg2, .playerID = iPlayer );
		}
		else if ( containi( szCommand, "item" ) != -1 )
		{
			iList = LIST_ITEMS;
			iNum1 = NameToItem( szArg1, .playerID = iPlayer );
			iNum2 = NameToItem( szArg2, .playerID = iPlayer );
		}
		else if ( containi( szCommand, "skill" ) != -1 )
		{
			iList = LIST_SKILLS;
			iNum1 = _:NameToSkill( szArg1, .playerID = iPlayer );
			iNum2 = _:NameToSkill( szArg2, .playerID = iPlayer );
		}
		else
		{
			iNum1 = NameToNum( LIST_POKEMON_NICKNAMES|LIST_ITEMS|LIST_SKILLS, szArg1, iPlayer, iList );
			if ( iNum1 > -1 )
				iNum2 = NameToNum( iList, szArg2, iPlayer );
		}

		if ( iNum1 != -1 && iNum1 == iNum2 )
		{
			client_print( iPlayer, print_chat, "[PokeMod] Cannot switch the same thing." );
		}

		new bool:bSwitchSuccess = false;

		switch ( iList )
		{
			case LIST_POKEMON_NICKNAMES:
			{
				if ( iNum1 == -1 )
				{
					CommandPokeMenu( iPlayer, "say /switchpoke", .bOnlyOwned = true, .iOwner = iPlayer );
				}
				else if ( iNum2 == -1 )
				{
					formatex( szSaid, charsmax(szSaid), "say /switchpoke ^"%s^"", szArg1 );
					CommandPokeMenu( iPlayer, szSaid, .bOnlyOwned = true, .iOwner = iPlayer );
				}
				else
				{
					PokeNumToName( iNum1, szArg1, charsmax(szArg1), .playerID = iPlayer );
					PokeNumToName( iNum2, szArg2, charsmax(szArg2), .playerID = iPlayer );

					PokemonTransfer( .player1 = iPlayer, .pokeNum1 = iNum1, .player2 = iPlayer, .pokeNum2 = iNum2 );

					bSwitchSuccess = true;
				}
			}
			case LIST_ITEMS:
			{
				if ( iNum1 == -1 )
				{
					CommandItemMenu( iPlayer, "say /switchitem", .bOnlyOwned = true, .iOwner = iPlayer );
				}
				else if ( iNum2 == -1 )
				{
					formatex( szSaid, charsmax(szSaid), "say /switchitem ^"%s^"", szArg1 );
					CommandItemMenu( iPlayer, szSaid, .bOnlyOwned = true, .iOwner = iPlayer );
				}
				else
				{
					new Int:iItemAmount1, iItemAmount2;
					new Int:iItemNum1 = PlayerHasItem( iPlayer, iNum1, iItemAmount1 );
					new Int:iItemNum2 = PlayerHasItem( iPlayer, iNum2, iItemAmount2 );

					if ( iItemNum1 != -1 && iItemNum2 != -1 )
					{
						new Array:playerItems = g_iPlayerItems[ iPlayer ];
						ArraySetCell( playerItems, ( ( iItemNum1 * _:PLAYER_ITEM ) + _:ITEM_ID ), iNum2 );
						ArraySetCell( playerItems, ( ( iItemNum1 * _:PLAYER_ITEM ) + _:ITEM_AMOUNT ), iItemAmount2 );

						ArraySetCell( playerItems, ( ( iItemNum2 * _:PLAYER_ITEM ) + _:ITEM_ID ), iNum1 );
						ArraySetCell( playerItems, ( ( iItemNum2 * _:PLAYER_ITEM ) + _:ITEM_AMOUNT ), iItemAmount1 );

						ItemToName( iNum1, szArg1, charsmax(szArg1), .playerID = iPlayer );
						ItemToName( iNum2, szArg2, charsmax(szArg2), .playerID = iPlayer );

						new String:szPlayerFile[ 64 ];
						nfv_player_file( iPlayer, szPlayerFile, charsmax( szPlayerFile ) );
						nfv_switch_names( szPlayerFile, "PokeItems", szArg1, szArg2 );

						bSwitchSuccess = true;
					}
				}
			}
			case LIST_SKILLS:
			{
				if ( iNum1 == -1 )
				{
					CommandSkillMenu( iPlayer, "say /switchskill", .bOnlyOwned = true, .iOwner = iPlayer );
				}
				else if ( iNum2 == -1 )
				{
					formatex( szSaid, charsmax(szSaid), "say /switchskill ^"%s^"", szArg1 );
					CommandSkillMenu( iPlayer, szSaid, .bOnlyOwned = true, .iOwner = iPlayer );
				}
				else
				{
					new Int:iPokeNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
					new Int:iSkillNum1 = PlayerHasSkill( iPlayer, iPokeNum, POKESKILL:iNum1 );
					new Int:iSkillNum2 = PlayerHasSkill( iPlayer, iPokeNum, POKESKILL:iNum2 );

					if ( iSkillNum1 != -1 && iSkillNum2 != -1 )
					{
						SkillToName( iNum1, szArg1, charsmax(szArg1), .playerID = iPlayer );
						SkillToName( iNum2, szArg2, charsmax(szArg2), .playerID = iPlayer );

						new Int:iSkillPP[ 2 ];
						iSkillPP[ 0 ] = g_iPlayerSkillPP[ iPlayer ][ iPokeNum ][ iSkillNum1 ];
						iSkillPP[ 1 ] = g_iPlayerSkillPP[ iPlayer ][ iPokeNum ][ iSkillNum2 ];
						new Int:iSkillCharges[ 2 ];
						iSkillCharges[ 0 ] = g_iPlayerSkillCharges[ iPlayer ][ iSkillNum1 ];
						iSkillCharges[ 1 ] = g_iPlayerSkillCharges[ iPlayer ][ iSkillNum2 ];

						g_iPlayerPokemonSkills[ iPlayer ][ iPokeNum ][ iSkillNum1 ] = POKESKILL:iNum2;
						g_iPlayerPokemonSkills[ iPlayer ][ iPokeNum ][ iSkillNum2 ] = POKESKILL:iNum1;
						g_iPlayerSkillPP[ iPlayer ][ iPokeNum ][ iSkillNum1 ] = iSkillPP[ 1 ];
						g_iPlayerSkillPP[ iPlayer ][ iPokeNum ][ iSkillNum2 ] = iSkillPP[ 0 ];
						g_iPlayerSkillCharges[ iPlayer ][ iSkillNum1 ] = iSkillCharges[ 1 ];
						g_iPlayerSkillCharges[ iPlayer ][ iSkillNum2 ] = iSkillCharges[ 0 ];

						SavePlayerPokeSkill( iPlayer, iPokeNum, iSkillNum1 );
						SavePlayerPokeSkill( iPlayer, iPokeNum, iSkillNum2 );

						bSwitchSuccess = true;
					}
				}
			}
			default:
			{
				new Int:iMenu = MenuCreate( "What would you like to switch?" );

				MenuAddItem( iMenu, "say /switchpoke", "Pokemon" );
				MenuAddItem( iMenu, "say /switchitem", "Items" );
				MenuAddItem( iMenu, "say /switchskill", "Skills" );

				MenuExit( iPlayer, iMenu, .bExitOption = true );

				MenuDisplay( iPlayer, iMenu, MENU_COMMAND );
			}
		}

		if ( bSwitchSuccess )
		{
			client_print( iPlayer, print_chat, "[PokeMod] You switched %s with %s.", szArg1, szArg2 );
		}
	}
	else if ( containi( szCommand, "item" ) != -1 && ( containi( szCommand, "info" ) != -1 || containi( szCommand, "help" ) != -1 || containi( szCommand, "dex" ) != -1 ) )
	{
		new Int:iItemID = NameToItem( szArg1, .playerID = iPlayer );
		if ( iItemID <= -1 )
		{
			if ( strlen( szArg1 ) > 0 )
				client_print( iPlayer, print_chat, "[PokeMod] Could not identify '%s' as a valid item.", szArg1 );
			CommandItemMenu( iPlayer, "say /iteminfo", .bOnlyOwned = false );
		}
		else
			ItemHelp( iPlayer, iItemID );
	}

	else if ( containi( szCommand, "player" ) != -1 && containi( szCommand, "poke" ) != -1 )
	{
		new String:szName[ 32 ];
		copy( szName, charsmax(szName), szArg1 );

		new Int:iPlayers[ MAX_PLAYERS ], Int:iPlayerCount;
		if ( !AdminGetPlayers( szName, iPlayers, iPlayerCount ) )
		{
			CommandPlayerMenu( iPlayer, "say /playerpoke", .bAllowSelf = true, .bAllowMultiple = true, .bAdminCmd = false );
		}
		else
		{
			PlayerViewPlayers( iPlayer, szName, iPlayers, iPlayerCount );
		}
	}

	else if ( containi( szCommand, "mypoke" ) != -1 )
	{
		new Int:iPokeNum = NameToPokeNum( szArg1, .playerID = iPlayer );
		if ( iPokeNum == -1 )
		{
			new Int:iPlayers[ MAX_PLAYERS ], Int:iPlayerCount;
			iPlayers[ iPlayerCount++ ] = iPlayer;
			PlayerViewPlayers( iPlayer, PlayerToName( iPlayer ), iPlayers, iPlayerCount );
		}
		else
		{
			PokemonShowInfo( .iViewer = iPlayer, .iOwner = iPlayer, .iPokeNum = iPokeNum );
		}
	}

	else if ( equali( szCommand, "rename" ) )
	{
		new Int:iPokeNum = NameToPokeNum( szArg1, .playerID = iPlayer );
		trim( szArg2 );

		if ( iPokeNum == -1 )
		{
			client_print( iPlayer, print_chat, "[PokeMod] Could not identify '%s' as a valid pokemon.", szArg1 );
		}
		else if ( !strlen( szArg2 ) )
		{
			client_print( iPlayer, print_chat, "[PokeMod] You must specify a new nickname. (Ex: /rename Charmander ^"Fire Tail^")" );
		}
		else
		{
			client_print( iPlayer, print_chat, "[PokeMod] %s now goes by the name of %s.", g_szPlayerPokemonNames[ iPlayer ][ iPokeNum ], szArg2 );

			copy( g_szPlayerPokemonNames[ iPlayer ][ iPokeNum ], charsmax( g_szPlayerPokemonNames[][] ), szArg2 );

			new String:szSaveName[ NAME_LEN ];
			SaveNameSlot( szSaveName, charsmax(szSaveName), iPokeNum );
			player_set_data( iPlayer, szSaveName, "Name", szArg2 );
		}
	}

	else if ( g_iState == PM_DEBUG && is_user_admin( iPlayer ) )
	{
		if ( equal( szCommand, "func" ) )
		{
			client_print( iPlayer, print_chat, "Function #%s", szSaid[ iCommandStart + 5 ] );
			ScriptCustomFunction( iPlayer, szSaid[ iCommandStart + 5 ] );
		}
		else if ( equal( szCommand, "script" ) )
		{
			client_print( iPlayer, print_chat, "Script: %s", szSaid[ iCommandStart + 7 ] );
			ScriptDoLine( iPlayer, szSaid[ iCommandStart + 7 ] );
		}
		else if ( equal( szCommand, "status" ) )
		{
			StatusApply( .iPlayer = iPlayer,
						.iInflictorID = iPlayer,
						.iStatus = NameToStatus( szArg1 ),
						.iAmount = max( 1, str_to_num( szArg2 ) )
						);
		}
	}

	else
	{
		new String:szCommandFunc[ 128 ];
		strtoupper( szCommand );
		TrieGetString( g_iSayCmdsTrie, szCommand, szCommandFunc, charsmax(szCommandFunc) );

		if ( contain( szCommandFunc, "%arg" ) != -1 )
		{
			replace_all( szCommandFunc, charsmax(szCommandFunc), "%arg%", szArg1 );
			replace_all( szCommandFunc, charsmax(szCommandFunc), "%arg1%", szArg1 );
			replace_all( szCommandFunc, charsmax(szCommandFunc), "%arg2%", szArg2 );
		}

		ScriptDoLine( iPlayer, szCommandFunc );
	}

	pokemod_funcend_debug( "CommandSay" );
	return PLUGIN_CONTINUE;
}

PM_FUNC_PUBLIC_ATTRIB CommandPokeskillDown( Int:iPlayer )
{
	if ( g_iState == PM_DISABLED )
		return PLUGIN_HANDLED;

	if ( iPlayer > MAX_PLAYERS )
		iPlayer -= TASK_POKESKILL_DOWN;

	new bool:bHoldingPokeSkill = bool:PlayerGetInfo( iPlayer, PINFO_POKESKILL_DOWN );
	if ( bHoldingPokeSkill && g_fSkillReadyTime[ iPlayer ] > get_gametime() )
	{
		SoundDeny( iPlayer );
		return PLUGIN_HANDLED;
	}

	PlayerSetInfo( iPlayer, PINFO_POKESKILL_DOWN, 1 );

	if ( PlayerGetInfo( iPlayer, PINFO_POKEITEM_DOWN ) )
	{
		PlayerSetInfo( iPlayer, PINFO_POKEITEM_DOWN, 0 );
		MenuMain( iPlayer, .bForceDisplay = true );
		return PLUGIN_HANDLED;
	}

	new String:szCommand[ 32 ];
	read_argv( 0, szCommand, charsmax(szCommand) );

	if ( szCommand[ 10 ] != EOS )
	{
		new Int:iSkillNum = str_to_num( szCommand[ 10 ] ) - 1;
		PlayerSetInfo( iPlayer, PINFO_ACTIVE_SKILLNUM, iSkillNum );
	}

	if ( is_user_alive( iPlayer ) )
	{
		if ( SkillMenu( iPlayer ) )
		{
			new Int:iSkillNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_SKILLNUM ) - 1;
			if ( iSkillNum > -1 )
			{
				SkillTimeCheckNull( iPlayer );

				new Int:iPokeNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
				new POKESKILL:iSkillID = g_iPlayerPokemonSkills[ iPlayer ][ iPokeNum ][ iSkillNum ];

				new SKILL:iSkillReturn = SkillCall( .skillID = iSkillID, .call = CALL_BIND_DOWN, .iPlayer = iPlayer, .skillNum = iSkillNum );

				switch( iSkillReturn )
				{
					case SKILL_USED, SKILL_READY:
					{
						set_task( 0.1, "CommandPokeskillDown", TASK_POKESKILL_DOWN + iPlayer );
					}
				}
			}
		}
		else
		{
			MenuMain( iPlayer, .bForceDisplay = true );
		}
	}
	else
	{
		MenuMain( iPlayer, .bForceDisplay = true );
	}

	return PLUGIN_HANDLED;
}

PM_FUNC_PUBLIC_ATTRIB CommandPokeskillUp( Int:iPlayer )
{
	if ( g_iState == PM_DISABLED )
		return PLUGIN_HANDLED;

	remove_task( TASK_POKESKILL_DOWN + iPlayer );

	PlayerSetInfo( iPlayer, PINFO_POKESKILL_DOWN, 0 );

	new Int:iSkillNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_SKILLNUM ) - 1;
	if ( iSkillNum > -1 )
	{
		SkillTimeCheckNull( iPlayer );

		new Int:iPokeNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
		new POKESKILL:iSkillID = g_iPlayerPokemonSkills[ iPlayer ][ iPokeNum ][ iSkillNum ];
		if ( SKILL_CALL:SkillInfo( iSkillID, SI_CALLTYPE ) & CALL_BIND_UP )
		{
			SkillCall( .skillID = iSkillID, .call = CALL_BIND_UP, .iPlayer = iPlayer, .skillNum = iSkillNum );
		}
	}

	return PLUGIN_HANDLED;
}

PM_FUNC_PUBLIC_ATTRIB CommandPokeitemDown( Int:iPlayer )
{
	PlayerSetInfo( iPlayer, PINFO_POKEITEM_DOWN, 1 );

	return PLUGIN_HANDLED;
}

PM_FUNC_PUBLIC_ATTRIB CommandPokeitemUp( Int:iPlayer )
{
	if ( g_iState == PM_DISABLED )
		return PLUGIN_HANDLED;

	if ( is_user_alive( iPlayer ) && PlayerGetInfo( iPlayer, PINFO_POKEITEM_DOWN ) )
	{
		ItemMenu( iPlayer );
	}

	PlayerSetInfo( iPlayer, PINFO_POKEITEM_DOWN, 0 );

	return PLUGIN_HANDLED;
}

PM_FUNC_NORM_ATTRIB CommandPlayerMenu( Int:iPlayer, String:szCommand[], bool:bAllowSelf = true, bool:bAllowMultiple = true, bool:bReshow = false, bool:bAdminCmd = false )
{
	if ( !iPlayer )
		return;

	new Int:iMenu = MenuCreate( "Select A Player" );

	new String:szData[ 64 ];

	if ( bAllowMultiple )
	{
		if ( bReshow )
			formatex( szData, charsmax(szData), "%s @ALL; %s", szCommand, szCommand );
		else
			formatex( szData, charsmax(szData), "%s @ALL", szCommand );
		MenuAddItem( iMenu, szData, "All Players" );

		if ( bReshow )
			formatex( szData, charsmax(szData), "%s @T; %s", szCommand, szCommand );
		else
			formatex( szData, charsmax(szData), "%s @T", szCommand );
		MenuAddItem( iMenu, szData, "All Terrorists" );

		if ( bReshow )
			formatex( szData, charsmax(szData), "%s @CT; %s", szCommand, szCommand );
		else
			formatex( szData, charsmax(szData), "%s @CT", szCommand );
		MenuAddItem( iMenu, szData, "All CTs" );
	}

	new String:szName[ NAME_LEN ];
	LoopThroughPlayersFlags( iPlayerID, PLAYER_FLAGS_NOHLTV )
	{
		if ( !bAllowSelf && iPlayer == iPlayerID )
			continue;

		formatex( szName, charsmax(szName), "#%d", get_user_userid( iPlayerID ) );
		CommandFormatter( szData, charsmax(szData), szCommand, szName, bReshow );

		PlayerToName( iPlayerID, szName, charsmax(szName) );
		MenuAddItem( iMenu, szData, szName );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, bAdminCmd ? MENU_ADMINCOMMAND : MENU_COMMAND );
}

PM_FUNC_NORM_ATTRIB CommandPokeMenu( Int:iPlayer, String:szCommand[], bool:bOnlyOwned = true, Int:iOwner = 0, bool:bReshow = false, bool:bAdminCmd = false )
{
	if ( !iPlayer )
		return;

	new Int:iMenu = MenuCreate( "Select A Pokemon" );

	new String:szData[ 64 ], String:szName[ NAME_LEN ];

	if ( bOnlyOwned )
	{
		for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
		{
			PokeNumToName( iPokeNum, szName, charsmax(szName), .playerID = iOwner );
			CommandFormatter( szData, charsmax(szData), szCommand, szName, bReshow );
			MenuAddItem( iMenu, szData, szName );
		}
	}
	else
	{
		for ( new Int:iPokeID = 1, iSize = ArraySize( g_iPokemonNames );
			iPokeID < iSize;
			iPokeID++
		){
			PokeToName( iPokeID, szName, charsmax(szName) );
			CommandFormatter( szData, charsmax(szData), szCommand, szName, bReshow );
			MenuAddItem( iMenu, szData, szName );
		}
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, bAdminCmd ? MENU_ADMINCOMMAND : MENU_COMMAND );
}

PM_FUNC_NORM_ATTRIB CommandItemMenu( Int:iPlayer, String:szCommand[], bool:bOnlyOwned = true, Int:iOwner = 0, bool:bReshow = false, bool:bAdminCmd = false )
{
	if ( !iPlayer )
		return;

	new Int:iMenu = MenuCreate( "Select An Item" );

	new String:szData[ 64 ], String:szName[ NAME_LEN ];

	for ( new Int:iItemID, Int:iSize = ArraySize( g_iItemNames );
		iItemID < iSize;
		iItemID++
	){
		if ( bOnlyOwned && !PlayerHasItem( iOwner, iItemID ) )
			continue;

		ItemToName( iItemID, szName, charsmax(szName) );
		CommandFormatter( szData, charsmax(szData), szCommand, szName, bReshow );
		MenuAddItem( iMenu, szData, szName );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, bAdminCmd ? MENU_ADMINCOMMAND : MENU_COMMAND );
}

PM_FUNC_NORM_ATTRIB CommandSkillMenu( Int:iPlayer, String:szCommand[], bool:bOnlyOwned = true, Int:iOwner = 0, bool:bReshow = false, bool:bAdminCmd = false )
{
	if ( !iPlayer )
		return;

	new Int:iMenu = MenuCreate( "Select A Skill" );

	new String:szData[ 64 ], String:szName[ NAME_LEN ];

	for ( new POKESKILL:iSkillID, Int:iSize = ArraySize( g_iSkillNames );
		_:iSkillID < iSize;
		iSkillID++
	){
		if ( bOnlyOwned && PlayerHasSkill( iOwner, PlayerGetInfo( iOwner, PINFO_ACTIVE_POKENUM ), iSkillID ) == -1 )
			continue;

		SkillToName( iSkillID, szName, charsmax(szName) );
		CommandFormatter( szData, charsmax(szData), szCommand, szName, bReshow );
		MenuAddItem( iMenu, szData, szName );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, bAdminCmd ? MENU_ADMINCOMMAND : MENU_COMMAND );
}

PM_FUNC_NORM_ATTRIB CommandLocationMenu( Int:iPlayer, String:szCommand[], bool:bReshow = false, bool:bAdminCmd = false )
{
	if ( !iPlayer )
		return;

	new Int:iMenu = MenuCreate( "Select A Location" );

	new String:szData[ 64 ], String:szName[ NAME_LEN ];

	for ( new Int:iLocation, Int:iSize = ArraySize( g_iLocationNames );
		iLocation < iSize;
		iLocation++
	){
		LocationToName( iLocation, szName, charsmax(szName) );
		CommandFormatter( szData, charsmax(szData), szCommand, szName, bReshow );
		MenuAddItem( iMenu, szData, szName );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, bAdminCmd ? MENU_ADMINCOMMAND : MENU_COMMAND );
}

PM_FUNC_NORM_ATTRIB CommandValueMenu( Int:iPlayer, String:szCommand[], String:szValueName[], String:szValues[][], Int:iValues = sizeof szValues, bool:bReshow = false, bool:bAdminCmd = false )
{
	if ( !iPlayer )
		return;

	new Int:iMenu = MenuCreate( "Select A %s Value", szValueName );

	new String:szData[ 64 ];

	for ( new Int:iValNum; iValNum < iValues; iValNum++ )
	{
		CommandFormatter( szData, charsmax(szData), szCommand, szValues[ iValNum ], bReshow );

		if ( contain( szData, "\" ) != -1 )
		{
			replace_all( szData, charsmax(szData), "\y", "" );
			replace_all( szData, charsmax(szData), "\w", "" );
			replace_all( szData, charsmax(szData), "\d", "" );
			replace_all( szData, charsmax(szData), "\r", "" );
			replace_all( szData, charsmax(szData), "\R", "" );
		}

		MenuAddItem( iMenu, szData, szValues[ iValNum ] );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, bAdminCmd ? MENU_ADMINCOMMAND : MENU_COMMAND );
}

CommandFormatter( String:szFullCommand[], Int:iLen, String:szCommand[], String:szParameter[], bool:bReshow )
{
	formatex( szFullCommand, iLen, "%s ^"%s^"", szCommand, szParameter );
	if ( bReshow )
	{
		add( szFullCommand, iLen, "; " );
		add( szFullCommand, iLen, szCommand );
	}
}

